package edu.ualberta.med.biobank.reporting; import java.awt.Color; import java.io.File; import java.io.InputStream; import java.net.URL; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.print.DocFlavor; import javax.print.PrintService; import javax.print.PrintServiceLookup; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRExporter; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.design.JasperDesign; import net.sf.jasperreports.engine.export.JRCsvExporter; import net.sf.jasperreports.engine.export.JRPrintServiceExporter; import net.sf.jasperreports.engine.export.JRPrintServiceExporterParameter; import net.sf.jasperreports.engine.xml.JRXmlLoader; import org.apache.commons.lang.StringUtils; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.printing.PrintDialog; import org.eclipse.swt.printing.PrinterData; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; import ar.com.fdvs.dj.core.layout.ClassicLayoutManager; import ar.com.fdvs.dj.domain.AutoText; import ar.com.fdvs.dj.domain.Style; import ar.com.fdvs.dj.domain.builders.FastReportBuilder; import ar.com.fdvs.dj.domain.constants.Border; import ar.com.fdvs.dj.domain.constants.Font; import ar.com.fdvs.dj.domain.constants.Transparency; import ar.com.fdvs.dj.domain.constants.VerticalAlign; import edu.ualberta.med.biobank.common.formatters.DateFormatter; import edu.ualberta.med.biobank.common.util.Holder; import edu.ualberta.med.biobank.gui.common.BgcPlugin; public class ReportingUtils { private static final String FILE_URI = "file://"; //$NON-NLS-1$ private static final String CSV_EXTENSION = ".csv"; //$NON-NLS-1$ private static final String PDF_EXTENSION = ".pdf"; //$NON-NLS-1$ public static final String SANSSERIF_TXT = "SansSerif"; //$NON-NLS-1$ public static Font sansSerif = new Font(Font.MEDIUM, SANSSERIF_TXT, false); public static Font sansSerifBold = new Font(Font.MEDIUM, SANSSERIF_TXT, true); public static final String JASPER_FILE_NAME = "BasicReport.jrxml"; //$NON-NLS-1$ public static final String JASPER_FILE_EXTENSION = ".jrxml"; //$NON-NLS-1$ public static PrinterData data; /** * if userIntegerProperties is set to true, then the map contained inside * 'list' should be contain [{0=value}, {1=value}...] instead of * [{name=value}...] (see issue #1312) */ public static JasperPrint createDynamicReport(String reportName, List<String> description, List<String> columnInfo, List<?> list, boolean useIntegerProperties) throws Exception { FastReportBuilder drb = new FastReportBuilder(); for (int i = 0; i < columnInfo.size(); i++) { String title = columnInfo.get(i); String property = title; if (useIntegerProperties) property = String.valueOf(i); drb.addColumn(title, property, String.class, 40, false) .setPrintBackgroundOnOddRows(true).setUseFullPageWidth(true); } String infos = StringUtils.join(description, System.getProperty("line.separator")); //$NON-NLS-1$ Map<String, Object> fields = new HashMap<String, Object>(); fields.put("title", reportName); //$NON-NLS-1$ fields.put("infos", infos); //$NON-NLS-1$ URL reportURL = ReportingUtils.class.getResource(JASPER_FILE_NAME); if (reportURL == null) { throw new Exception(NLS.bind( Messages.ReportingUtils_jasperfile_error_msg, JASPER_FILE_NAME.replaceAll(JASPER_FILE_EXTENSION, ""))); //$NON-NLS-1$ } drb.setTemplateFile(reportURL.getFile()); drb.addAutoText(AutoText.AUTOTEXT_PAGE_X_OF_Y, AutoText.POSITION_FOOTER, AutoText.ALIGNMENT_RIGHT, 200, 40); drb.addAutoText( NLS.bind(Messages.ReportingUtils_footer_print_msg, DateFormatter.formatAsDateTime(new Date())), AutoText.POSITION_FOOTER, AutoText.ALIGNMENT_LEFT, 200); Style headerStyle = new Style(); headerStyle.setFont(ReportingUtils.sansSerifBold); // headerStyle.setHorizontalAlign(HorizontalAlign.CENTER); headerStyle.setBorderBottom(Border.THIN); headerStyle.setVerticalAlign(VerticalAlign.MIDDLE); headerStyle.setBackgroundColor(Color.LIGHT_GRAY); headerStyle.setTransparency(Transparency.OPAQUE); Style detailStyle = new Style(); detailStyle.setFont(ReportingUtils.sansSerif); drb.setDefaultStyles(null, null, headerStyle, detailStyle); JRDataSource ds = new JRBeanCollectionDataSource(list); JasperPrint jp = DynamicJasperHelper.generateJasperPrint(drb.build(), new ClassicLayoutManager(), ds, fields); return jp; } public static JasperPrint createStandardReport(String reportName, Map<String, Object> parameters, List<?> list) throws Exception { InputStream reportStream = ReportingUtils.class .getResourceAsStream(reportName + JASPER_FILE_EXTENSION); if (reportStream == null) { throw new Exception(NLS.bind( Messages.ReportingUtils_jasperfile_error_msg, reportName)); } JasperDesign jdesign = JRXmlLoader.load(reportStream); JasperReport report = JasperCompileManager.compileReport(jdesign); return JasperFillManager.fillReport(report, parameters, new JRBeanCollectionDataSource(list)); } public static void saveReport(JasperPrint jasperPrint, String path) throws Exception { if (path == null) return; if (path.startsWith(FILE_URI)) { path = path.substring(FILE_URI.length()); } if (path.endsWith(PDF_EXTENSION)) { JasperExportManager.exportReportToPdfFile(jasperPrint, path); } else if (path.endsWith(CSV_EXTENSION)) { JRExporter csvExporter = new JRCsvExporter(); csvExporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); csvExporter.setParameter(JRExporterParameter.OUTPUT_FILE, new File( path)); csvExporter.exportReport(); } else { throw new Exception(Messages.ReportingUtils_extension_error_msg); } } private static PrintService getPrinterService(PrinterData data) { // use the standard java method to retrieve print services PrintService[] services = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PRINTABLE, null); PrintService service = null; // try to find the correct PrintService using the Swt PrinterData // information for (PrintService ps : services) { if (ps.getName().equals(data.name)) { service = ps; } } return service; } private static void printViaPrinter(PrinterData data, JasperPrint jasperPrint) throws Exception { PrintService service = getPrinterService(data); if (service != null) { JRExporter exporter = new JRPrintServiceExporter(); exporter .setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter( JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET, service.getAttributes()); exporter.setParameter( JRPrintServiceExporterParameter.DISPLAY_PAGE_DIALOG, Boolean.FALSE); exporter.setParameter( JRPrintServiceExporterParameter.DISPLAY_PRINT_DIALOG, Boolean.FALSE); try { exporter.exportReport(); } catch (JRException e) { throw new Exception( Messages.ReportingUtils_jasper_printing_error_msg); } } else { throw new Exception(NLS.bind( Messages.ReportingUtils_printer_error_msg, data.name)); } } private static void printViaFile(PrinterData data, JasperPrint jasperPrint) throws Exception { String fileName = null; // data.fileName is typically "FILE:" instead of null. if (data.fileName != null && data.fileName.endsWith(PDF_EXTENSION)) { fileName = data.fileName; } else { // on windows a custom dialog is required to print to file. FileDialog fd = new FileDialog(PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getShell(), SWT.SAVE); fd.setOverwrite(true); fd.setText(Messages.ReportingUtils_pdf_file_msg); String[] filterExt = { "*" + PDF_EXTENSION }; //$NON-NLS-1$ fd.setFilterExtensions(filterExt); fd.setFileName(DateFormatter.formatAsDateTime(new Date())); final String path = fd.open(); fileName = path; } if (fileName == null) { return; } if (fileName.endsWith(PDF_EXTENSION)) { if (fileName.startsWith(FILE_URI)) { fileName = fileName.substring(FILE_URI.length()); } JasperExportManager.exportReportToPdfFile(jasperPrint, fileName); } else { throw new Exception(NLS.bind( Messages.ReportingUtils_file_type_error_msg, fileName)); } } public static void printReport(final JasperPrint jasperPrint) throws Exception { // Use SWT PrintDialog instead of the JasperReport method that use java // swing gui. final Display display = Display.getDefault(); final Holder<Exception> exception = new Holder<Exception>(null); display.syncExec(new Runnable() { @Override public void run() { Shell shell = display.getActiveShell(); PrintDialog dialog = new PrintDialog(shell, SWT.NONE); PrinterData data = dialog.open(); // if data is null : user cancelled print. if (data != null) { try { if (data.printToFile == true) { printViaFile(data, jasperPrint); } else { try { printViaPrinter(data, jasperPrint); } catch (Exception e) { BgcPlugin .openAsyncError( Messages.ReportingUtils_printing_error_title, null, e, Messages.ReportingUtils_printing_error_msg); printViaFile(data, jasperPrint); } } } catch (Exception e) { exception.setValue(e); } } } }); if (exception.getValue() != null) { throw exception.getValue(); } } }